package com.dkts.oil.test;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.*;
import java.nio.file.*;
import java.util.*;

public class FleetAnalysis {

    // 最大距离差，用于判断是否同编队（单位：米）
    private static final double MAX_DISTANCE_DIFF = 1000.0;
    // 最大时间差（单位：秒）
    private static final long MAX_TIME_DIFF = 60 * 60; // 1小时

    // 计算两个船只之间的距离（使用Haversine公式）
    private static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        final int R = 6371000; // 地球半径，单位：米
        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);
        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) +
                Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                        Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return R * c; // 返回结果，单位：米
    }

    // 计算两个轨迹点的时间差（单位：秒）
    private static long calculateTimeDiff(CSVRecord point1, CSVRecord point2) {
        long time1 = Long.parseLong(point1.get("time"));
        long time2 = Long.parseLong(point2.get("time"));
        return Math.abs(time1 - time2);
    }

    // 查找同编队的船
    public static List<List<CSVRecord>> findFleet(List<List<CSVRecord>> allTrajectories) {
        List<List<CSVRecord>> fleetGroups = new ArrayList<>();
        Set<CSVRecord> visited = new HashSet<>();

        // 遍历每个轨迹，比较每个船只的轨迹
        for (List<CSVRecord> trajectory : allTrajectories) {
            if (visited.contains(trajectory.get(0))) {
                continue;  // 如果已经访问过，则跳过
            }

            List<CSVRecord> fleet = new ArrayList<>();
            fleet.add(trajectory.get(0));  // 加入第一个轨迹点

            for (List<CSVRecord> compareTrajectory : allTrajectories) {
                if (visited.contains(compareTrajectory.get(0))) {
                    continue;
                }

                // 比较两个轨迹是否属于同编队
                boolean isFleet = compareToFleet(fleet, compareTrajectory);
                if (isFleet) {
                    fleet.add(compareTrajectory.get(0));  // 加入编队
                    visited.add(compareTrajectory.get(0));
                }
            }

            fleetGroups.add(fleet);  // 将找到的编队添加到结果中
        }

        return fleetGroups;
    }

    // 判断两个轨迹是否属于同一编队
    private static boolean compareToFleet(List<CSVRecord> fleet, List<CSVRecord> compareTrajectory) {
        for (CSVRecord point1 : fleet) {
            for (CSVRecord point2 : compareTrajectory) {
                long timeDiff = calculateTimeDiff(point1, point2);
                double distanceDiff = calculateDistance(
                        Double.parseDouble(point1.get("lat")),
                        Double.parseDouble(point1.get("lon")),
                        Double.parseDouble(point2.get("lat")),
                        Double.parseDouble(point2.get("lon"))
                );

                if (timeDiff <= MAX_TIME_DIFF && distanceDiff <= MAX_DISTANCE_DIFF) {
                    return true;  // 如果时间差和距离差都在阈值内，则认为是同编队
                }
            }
        }
        return false;  // 如果没有符合的条件，则不是同编队
    }

    // 从CSV文件加载轨迹数据
    public static List<List<CSVRecord>> loadTrajectoryData(String filePath) throws IOException {
        List<List<CSVRecord>> trajectories = new ArrayList<>();
        try (Reader reader = new FileReader(filePath)) {
            CSVParser csvParser = CSVFormat.DEFAULT.withHeader().parse(reader);
            Map<String, List<CSVRecord>> mmsiMap = new HashMap<>();

            // 按照MMSI分组轨迹数据
            for (CSVRecord record : csvParser) {
                String mmsi = record.get("mmsi");
                if (!mmsiMap.containsKey(mmsi)) {
                    mmsiMap.put(mmsi, new ArrayList<>());
                }
                mmsiMap.get(mmsi).add(record);
            }

            // 将每个MMSI的轨迹列表添加到轨迹数据
            for (Map.Entry<String, List<CSVRecord>> entry : mmsiMap.entrySet()) {
                trajectories.add(entry.getValue());
            }
        }
        return trajectories;
    }

    // 将轨迹数据输出为GeoJSON格式
    public static void writeGeoJson(List<CSVRecord> trajectory, String directoryPath, String mmsi) throws IOException, JSONException {
        // 创建文件夹
        File dir = new File(directoryPath);
        if (!dir.exists()) {
            dir.mkdirs();  // 如果文件夹不存在，则创建
        }

        // GeoJSON内容
        JSONArray features = new JSONArray();
        JSONArray coordinates = new JSONArray();

        // 将轨迹点连接成 LineString
        for (CSVRecord record : trajectory) {
            double lat = Double.parseDouble(record.get("lat"));
            double lon = Double.parseDouble(record.get("lon"));
            coordinates.put(new JSONArray().put(lon).put(lat));  // 存储经纬度顺序
        }

        // 创建 GeoJSON feature
        JSONObject feature = new JSONObject();
        feature.put("type", "Feature");
        feature.put("geometry", new JSONObject()
                .put("type", "LineString")
                .put("coordinates", coordinates)
        );
        feature.put("properties", new JSONObject()
                .put("mmsi", mmsi)
                .put("start_time", trajectory.get(0).get("time"))
                .put("end_time", trajectory.get(trajectory.size() - 1).get("time"))
        );
        features.put(feature);

        // 创建 GeoJSON 文件
        JSONObject geoJson = new JSONObject();
        geoJson.put("type", "FeatureCollection");
        geoJson.put("features", features);

        // 写入文件
        String geoJsonFilePath = directoryPath + File.separator + mmsi + "_trajectory.geojson";
        try (FileWriter fileWriter = new FileWriter(geoJsonFilePath)) {
            fileWriter.write(geoJson.toString(4));
        }
    }

    public static void main(String[] args) {
        // 假设CSV文件路径
        String filePath = "C:\\Users\\heyou\\Documents\\WeChat Files\\wxid_86da35bc9zvi21\\FileStorage\\File\\2025-05\\c9a6717b7d2f5293cf7cd2ed05a0494c_2e2437ef9cd58c0d39af05569deeb4be_8.csv";
        String outputDirectory = "output";  // 输出文件夹

        try {
            // 加载轨迹数据
            List<List<CSVRecord>> allTrajectories = loadTrajectoryData(filePath);

            // 查找同编队的船
            List<List<CSVRecord>> fleetGroups = findFleet(allTrajectories);

            // 输出每个编队的信息和轨迹数据
            for (int i = 0; i < fleetGroups.size(); i++) {
                List<CSVRecord> fleet = fleetGroups.get(i);
                System.out.println("编队 " + (i + 1) + ": ");
                for (CSVRecord record : fleet) {
                    System.out.println("  MMSI: " + record.get("mmsi") + ", Time: " + record.get("time"));
                }

                // 为每个编队创建文件夹
                String fleetFolderPath = outputDirectory + File.separator + "fleet_" + (i + 1);
                for (CSVRecord record : fleet) {
                    String mmsi = record.get("mmsi");
                    // 输出每个MMSI的轨迹点为GeoJSON
                    writeGeoJson(fleet, fleetFolderPath, mmsi);
                    System.out.println("编队 " + (i + 1) + " 的轨迹已保存为: " + fleetFolderPath + File.separator + mmsi + "_trajectory.geojson");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    }
}
